home *** CD-ROM | disk | FTP | other *** search
- program Dict;
- (* simple dictionary using a btree.
- The program reads in an ASCII file with one word per line and stores the
- words in an btree. A btree is something like binary tree but every node
- can have more than two descent nodes. This is done by linked list.
-
- This method has two advantages:
- * when a word is wrong you can easily give some proposes how the word
- is written correctly (just change the path in the tree a little)
- * bigger dict. may save space. E.g "base, basicly, basement" etc.
- share the same path on the first three niveaus.
-
- ATTENTION! I don't free any mem I've allocated. This is done by the
- heap manager (i.e. he allocates large blockes and releases them } when
- the program ends. But this can be added easily.
-
- Also, there is no function included that deletes words (I don't need it in
- my project). I suggest it is not that easy to add such a function but
- have a try ;-))
-
- *)
-
- { $DEFINE DEBUG} { if DEBUG is defined (just erase space between "{" and "$")
- then some actions are logged while building the tree and
- while searching. }
-
- const debugfile = 'dict.log'; { log file (if needed) }
- dictFileName = 'dict.dat'; { data input (words in ASCII) }
-
- type PNode = ^TNode;
- TNode = record
- Character : Char; { the current character }
- WordEnd : Boolean; { is this char. the last of one word?}
- right,down: PNode; { right: points to next char on the
- same niveau
- down : points to the next char in
- word }
- {$IFDEF DEBUG}
- Level : byte; { level of the tree }
- {$ENDIF }
- end;
-
- var BTree: PNode; { our tree }
- DictFile: Text; { our ascii dictionary }
- {$IFDEF DEBUG}
- var f: Text; { log file handle }
- {$ENDIF }
-
-
- procedure CreateBTree;
- { just initalizes the tree w/ a dummy element }
- begin
- Btree:=NIL;
- New(Btree);
- BTree^.character:=#$1A; { #$1A is END-OF-FILE. shouldn't be used in any word }
- BTree^.right:=NIL;
- Btree^.down:=NIL;
- BTree^.Wordend:=true;
- {$IFDEF DEBUG}
- BTree^.level:=1;
- writeln(f,'B-Tree with dummy element created.');
- {$ENDIF }
- end;
-
- {$IFDEF DEBUG}
- function GetNode(Character: Char; LevelPtr: PNode; Level: byte): PNode;
- {$ELSE }
- function GetNode(Character: Char; LevelPtr: PNode): PNode;
- {$ENDIF }
- { returns the node in Level "LevelPtr" that contains "Character".
- if there is no node, it is created }
- var p: PNode;
- begin
- if levelptr=NIL then begin
- New(P);
- P^.right:=NIL;
- P^.down:=NIL;
- P^.character:=character;
- P^.WordEnd:=False;
- {$IFDEF DEBUG}
- P^.Level:=Level;
- writeln(f,'#New niveau-node enterd. Content of the first node: '+
- ' "',character,'". Level ',level);
- {$ENDIF }
- GetNode:=p;
- end else begin
- p:=levelptr;
- while (p^.right<>NIL) and (p^.character<>Character) do p:=p^.right;
- if p^.character=character then
- begin
- getnode:=p;
- {$IFDEF DEBUG}
- writeln(f,'Node "',character,'" found on level ',level,'.');
- {$ENDIF }
- end
- else begin
- { p^.right is NIL! }
- new(p^.right);
- p:=p^.right;
- p^.character:=character;
- p^.right:=NIL;
- p^.down:=nil;
- p^.wordend:=false;
- {$IFDEF DEBUG}
- p^.level:=level;
- writeln(f,'#Entered new node. Content "',character,'". Level ',level);
- {$ENDIF }
- GetNode:=p;
- end; {if}
- end; { if }
- end;
-
- procedure InsertWord(wort: string);
- { inserts the word "wort" into btree }
- var p1,p2,p3: PNode;
- i: byte;
- begin
- if wort='' then exit;
- p2:=btree;
- for i:=1 to length(wort) do
- begin
- {$IFDEF DEBUG}
- p1:=getnode(wort[i],p2,i);
- {$ELSE}
- p1:=getnode(wort[i],p2);
- {$ENDIF}
- if p2=NIL then p3^.down:=p1;
- p3:=p1;
- p2:=p1^.down;
- end;
- p1^.wordend:=true;
- {$IFDEF DEBUG}
- writeln(f,'Wort "',wort,'" eingetragen.');
- {$ENDIF }
- end;
-
- function ProofWord(Wort: string): boolean;
- { returns true if "wort" is in our dictionary }
- var P1,p2: PNode;
- I: Byte;
- begin
- ProofWord:=FALSE;
- if wort='' then exit;
- p1:=BTree;
- i:=1;
- {$IFDEF DEBUG}
- writeln(f,'Searching for word "',wort,'".');
- {$ENDIF }
- while (p1<>NIL) and (length(wort)>=i) do begin
- while (p1^.right<>NIL) and (p1^.character<>wort[i]) do p1:=p1^.right;
- if p1^.character=wort[i] then begin
- inc(i);
- p2:=p1;
- p1:=p1^.down;
- {$IFDEF DEBUG}
- writeln(f,'Character "',wort[i-1],'" found on level ',i-1,'.');
- {$ENDIF }
- end else p1:=NIL;
- end;
- if (i=length(wort)+1) and (p2^.wordend) then proofword:=TRUE;
- end;
-
-
- var OldExitProcPtr: Pointer;
-
- procedure MyExitProc;far;
- begin
- ExitProc:=OldExitProcPtr;
- if exitcode = 214 then writeln('Huston! We''ve got a pointer problem!');
- {$IFDEF DEBUG}
- close(f);
- {$ENDIF }
- end;
-
- var s: String;
-
- begin
- OldExitProcPtr:=ExitProc;
- ExitProc:=@MyExitProc;
- {$IFDEF DEBUG}
- assign(f,debugfile);
- rewrite(f);
- {$ENDIF }
- assign(dictfile,dictfilename);
- createBTree;
- reset(dictfile);
- write('Reading dictionary...');
- while not eof(dictfile) do
- begin
- readln(dictfile,s);
- insertword(s);
- end;
- writeln('done.');
- writeln('Request mode. End with "END"!');
- s:='';
- repeat
- write('OK>');
- readln(s);
- if s<>'END' then
- if proofword(s) then writeln('Word found!',#7)
- else writeln('Word not fond!');
-
- until s='END';
- {$IFDEF DEBUG}
- close(f);
- {$ENDIF }
- ExitProc:=OldExitProcPtr;
- end.=====================Code ends===============================